package com.fr.schedule.entry;

import com.fr.fs.schedule.ScheduleContext;
import com.fr.fs.schedule.job.SAPSynJob;
import com.fr.fs.schedule.trigger.ITrigger;
import com.fr.fs.schedule.trigger.OnceITrigger;
import com.fr.general.FRLogger;
import com.fr.json.JSONArray;
import com.fr.json.JSONException;
import com.fr.json.JSONObject;
import com.fr.schedule.task.SAPSynTask;
import com.fr.schedule.util.ScheduleConstants;
import com.fr.schedule.util.ScheduleLogUtils;
import com.fr.schedule.util.TaskConfig;
import com.fr.stable.StringUtils;
import com.fr.third.org.quartz.JobDetail;
import com.fr.third.org.quartz.Scheduler;
import com.fr.third.org.quartz.SchedulerException;
import com.fr.third.org.quartz.Trigger;
import com.fr.web.platform.TransmitParameters;

import java.util.Date;

public class SAPSynManager {
	public static final String SAPSYN_GROUP_NAME = "SAPSyn";
    private static FRLogger log = FRLogger.getLogger();
	public static JSONArray getAllTasks() {
		JSONArray tasksJSONA = new JSONArray();
		
		java.util.List tasksList = ScheduleContext.createDAOSession().list(SAPSynTask.class);
		for(int i=0; i < tasksList.size(); i++){
			SAPSynTask task = (SAPSynTask) tasksList.get(i);
			try {
				JSONObject taskJSON = task.createJSONConfig();
				tasksJSONA.put(taskJSON);
			} catch (JSONException e) {
                ScheduleLogUtils.error(e);
			}
		}
		
		return tasksJSONA;
	}
	
	public static void addOrUpdateTask(JSONObject taskJSON) {
		try{
			String name = taskJSON.getString(ScheduleConstants.NAME);
			String description = StringUtils.EMPTY;
			String repeatTime = taskJSON.getString(ScheduleConstants.REPEAT_TIME);
			String repeatTimes = taskJSON.getString(ScheduleConstants.REPEAT_TIMES);
			
			ITrigger iTrigger = EntryManager.parseITrigger(taskJSON.getJSONObject(ScheduleConstants.ITRIGGER));
			
			JSONArray taskParametersJSONA = taskJSON.getJSONArray(ScheduleConstants.TRANSMIT_PARAMETERS);
			TransmitParameters taskParameters = TransmitParameters.parseJSON(taskParametersJSONA);
			
			JSONArray tran = taskJSON.getJSONArray("transfers");
			
			SAPSynTask newTask = null;
			
			ITrigger oldITrigger= null;
			if(taskJSON.has(ScheduleConstants.ID)){
				newTask = (SAPSynTask)ScheduleContext.createDAOSession().load(SAPSynTask.class, taskJSON.getLong(ScheduleConstants.ID));
				oldITrigger = newTask.getITrigger();
				newTask.setName(name);
				newTask.setDescription(description);
				newTask.setITrigger(iTrigger);
				newTask.setCounts(0);
				newTask.setTaskParameters(taskParameters);
				newTask.setRepeatTime(repeatTime);
				newTask.setRepeatTimes(repeatTimes);
				newTask.setTransfers(tran.toString());
			} else {
                TaskConfig taskConfig = new TaskConfig();
                taskConfig.setName(name);
                taskConfig.setDescription(description);
                taskConfig.setiTrigger(iTrigger);
                taskConfig.setTaskParameters(taskParameters);
                taskConfig.setRepeatTime(repeatTime);
                taskConfig.setRepeatTimes(repeatTimes);
                taskConfig.setTransfer(tran.toString());
				newTask = new SAPSynTask(taskConfig);
			}
			
			ScheduleContext.createDAOSession().saveOrUpdate(newTask);
			scheduleTask(newTask, false, oldITrigger);
		} catch (JSONException e) {
            ScheduleLogUtils.error(e);
		}
	}
	
	public static void scheduleTask(SAPSynTask newTask, boolean isRestart, ITrigger oldTrigger) {
		JobDetail jobDetail = new JobDetail(newTask.getName(), SAPSYN_GROUP_NAME, SAPSynJob.class);
		if(isRestart) {
			jobDetail.setName(jobDetail.getName() + Math.random()*10000);
		}
		jobDetail.setDescription(newTask.getDescription());
		jobDetail.getJobDataMap().put(ScheduleConstants.__TASK__, newTask.getId());
		if(isRestart) {
			jobDetail.getJobDataMap().put(ScheduleConstants.__RESTARTTASK__, newTask);
		}
		ITrigger iTrigger = newTask.getITrigger();
		Trigger trigger = iTrigger.createTrigger();
		if(isRestart) {
			trigger.setName(trigger.getName() + "_Restart_" + Math.random());
		}
		trigger.setJobName(jobDetail.getName());
		trigger.setJobGroup(jobDetail.getGroup());
		Scheduler scheduler  = ScheduleContext.getScheduler();
		try {
			Trigger[] triggers = scheduler.getTriggersOfJob(jobDetail.getName(), jobDetail.getGroup());
			if(triggers.length > 0 && oldTrigger != null){
				scheduler.rescheduleJob(oldTrigger.createTrigger().getName(), oldTrigger.createTrigger().getGroup(), trigger);
			} else {
				scheduler.scheduleJob(jobDetail,  trigger);
			}
		} catch (SchedulerException e) {
            ScheduleLogUtils.error(e);
		}
	}
	
	public static void delTasks(String taskIdsString) {
		String [] ids = taskIdsString.split(ScheduleConstants.ID_SPACER);
		for(int i = 0; i < ids.length; i++){
			long taskId = Long.parseLong(ids[i]);
			Object task = ScheduleContext.createDAOSession().load(SAPSynTask.class, taskId);
			deleteTask((SAPSynTask)task);
		}
	}
	
	private static void deleteTask(SAPSynTask task) {
		Scheduler scheduler  = ScheduleContext.getScheduler();
		try {
			scheduler.deleteJob((task).getName(), SAPSYN_GROUP_NAME);
		} catch (SchedulerException e) {
            ScheduleLogUtils.error(e);
		}
		ScheduleContext.createDAOSession().delete(task);
	}
	
	public static void reStartTask(SAPSynTask task, long delay) {
		task.setCounts(task.getCounts() + 1);
		SAPSynTask cloneTask = null;
		try {
			cloneTask = (SAPSynTask)task.clone();
		} catch (CloneNotSupportedException e) {
			log.error(e.getMessage());
		}
		if(cloneTask.getCounts() > Integer.parseInt(task.getRepeatTimes()) || Integer.parseInt(task.getRepeatTimes()) == 0) {
			return;
		}
		OnceITrigger onceItrigger = new OnceITrigger();
		onceItrigger.setStartType(ITrigger.ON);
		onceItrigger.setId(task.getITrigger().getId());
		onceItrigger.setStartTime(new Date((new Date()).getTime() + delay));
		cloneTask.setITrigger(onceItrigger);
		scheduleTask(cloneTask, true, onceItrigger);
	}
	
	public static int stateJob(long taskId) {
		int state = -1;
		Scheduler scheduler  = ScheduleContext.getScheduler();
		SAPSynTask task = (SAPSynTask)ScheduleContext.createDAOSession().load(SAPSynTask.class, taskId);
		
		if (task.getITrigger().getStartTime() != null && task.getITrigger().getStartTime().getTime() > System.currentTimeMillis()) {
			return ITrigger.WAITSTATE;
		}
		try {
			Trigger trigger;
			Trigger[] triggers = scheduler.getTriggersOfJob(task.getName(), SAPSYN_GROUP_NAME);
			if(triggers.length > 0){
				trigger = triggers[0];
				state = scheduler.getTriggerState(trigger.getName(), trigger.getGroup());
				if(state == 0){
					scheduler.pauseJob(trigger.getJobName(), trigger.getJobGroup());
				}else{
					scheduler.resumeJob(trigger.getJobName(), trigger.getJobGroup());
				}
				state = scheduler.getTriggerState(trigger.getName(), trigger.getGroup());
			}
		} catch (SchedulerException e) {
            ScheduleLogUtils.error(e);
		}
		return state;
	}
}
